const router = require("express").Router();
const mysql = require("./../mysql");
const User = require("./../mysql/collection/User");
const Order = require("./../mysql/collection/Order");
const uuid = require("uuid");
const md5 = require("md5");
const jwt = require("jsonwebtoken");
const config = require("../config");
let axios = require("axios");

router.get("/", (req, res, next) => {
  res.send("用户相关接口");
});
/**
 * @swagger
 * /api/user/docheckphone:
 *   post:
 *     summary: 验证手机号码是否被注册过
 *     tags: [用户端-用户管理]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               tel:
 *                 type: string
 *                 description: 手机号码
 *             required:
 *               - tel
 *     responses:
 *       200:
 *         description: 验证成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '继续注册'
 */
router.post("/docheckphone", (req, res, next) => {
  const { tel } = req.body;
  mysql.find(User, { tel }, { _id: 0, __v: 0 }).then((data) => {
    if (data.length === 0) {
      // 没有被注册过
      res.send({
        code: "200",
        message: "继续注册",
      });
    } else {
      if (data[0].password === "") {
        // 没有被注册过
        res.send({
          code: "200",
          message: "继续注册",
        });
      } else {
        res.send({
          code: "10005",
          message: "该用户已被注册",
        });
      }
    }
  });
});

function getTelCode() {
  return 10000 + Math.floor(Math.random() * 90000);
}
function getRandomName() {
  return "123123";
}

/**
 * @swagger
 * /api/user/dosendmsgcode:
 *   post:
 *     summary: 发送短信验证码
 *     tags: [用户端-用户管理]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               tel:
 *                 type: string
 *                 description: 手机号码
 *             required:
 *               - tel
 *     responses:
 *       200:
 *         description: 发送成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '发送短信验证码成功'
 */
router.post("/dosendmsgcode", (req, res, next) => {
  const { tel } = req.body;
  const telcode = getTelCode();
  mysql.find(User, { tel }, { _id: 0, __v: 0 }).then((data) => {
    if (data.length === 0) {
      // 没有该用户，创建一个新用户
      const userid = uuid.v4();
      mysql
        .insert(User, {
          userid,
          tel,
          telcode,
          username: getRandomName(),
          password: "",
        })
        .then(() => {
          // 发送短信验证码
          res.send({
            code: "200",
            message: "发送短信验证码成功",
            data: telcode, // 真实情况不应该写
          });
        });
    } else {
      if (data[0].telcode !== "") {
        // 上一次获取过验证码，但是未注册完成，更新验证码
        mysql.update(User, { tel }, { $set: { telcode } }).then(() => {
          // 发送短信验证码
          res.send({
            code: "200",
            message: "发送短信验证码成功",
            data: telcode, // 真实情况不应该写
          });
        });
      }
    }
  });
});
/**
 * @swagger
 * /api/user/docheckcode:
 *   post:
 *     summary: 验证短信验证码
 *     tags: [用户端-用户管理]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               tel:
 *                 type: string
 *                 description: 手机号码
 *               telcode:
 *                 type: string
 *                 description: 验证码
 *               password:
 *                 type: string
 *                 description: 密码
 *             required:
 *               - tel
 *               - telcode
 *               - password
 *     responses:
 *       200:
 *         description: 验证成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '注册成功'
 */
router.post("/docheckcode", (req, res, next) => {
  const { tel, telcode, password } = req.body;
  mysql
    .find(User, { tel, telcode }, { _id: 0, __v: 0 })
    .then((data) => {
      if (data.length === 0) {
        res.send({
          code: "10006",
          message: "验证码错误",
        });
      } else {
        // 验证码正确，更新密码
        mysql
          .update(
            User,
            { tel },
            { $set: { password: md5(password), telcode: "" } }
          )
          .then(() => {
            res.send({
              code: "200",
              message: "注册成功",
            });
          });
      }
    });
});

/**
 * @swagger
 * /api/user/dologin:
 *   post:
 *     summary: 用户登录
 *     tags: [用户端-用户管理]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               loginname:
 *                 type: string
 *                 description: 登录名（手机号/用户名/邮箱）
 *               password:
 *                 type: string
 *                 description: 密码
 *             required:
 *               - loginname
 *               - password
 *     responses:
 *       200:
 *         description: 登录成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '登录成功'
 *                 data:
 *                   type: object
 *                   properties:
 *                     token:
 *                       type: string
 *                       description: 访问令牌
 *                     refresh-token:
 *                       type: string
 *                       description: 刷新令牌
 *                     userid:
 *                       type: string
 *                       description: 用户ID
 */
router.post("/dologin", (req, res, next) => {
  const { loginname, password } = req.body;
  mysql
    .find(
      User,
      {
        $or: [
          { username: loginname },
          { tel: loginname },
          { email: loginname },
        ],
      },
      { _id: 0, __v: 0 }
    )
    .then((data) => {
      if (data.length === 0) {
        // 这个用户不存在
        res.send({
          code: "10010",
          message: "该用户不存在",
        });
      } else {
        // 有该用户，需要验证密码（加密）
        mysql
          .find(
            User,
            {
              $or: [
                { username: loginname, password: md5(password) },
                { tel: loginname, password: md5(password) },
                { email: loginname, password: md5(password) },
              ],
            }
            // { _id: 0, __v: 0 }
          )
          .then((result) => {
            console.log(result);
            if (result.length === 0) {
              // []
              // 密码错误
              res.send({
                code: "10011",
                message: "密码错误",
              });
            } else {
              // [{ tel: '', ....}]
              // 登录成功
              // 返回用户需要的相关信息
              const token = jwt.sign(
                { tel: result[0].tel, userid: result[0].userid },
                config.jwt.secret,
                {
                  expiresIn: config.jwt.access_token_expires, // 7天
                }
              );
              
              // 生成refresh token，有效期更长
              const refreshToken = jwt.sign(
                { tel: result[0].tel, userid: result[0].userid, type: 'refresh' },
                config.jwt.refresh_secret,
                {
                  expiresIn: config.jwt.refresh_token_expires, // 30天
                }
              );
              
              const userid = result[0].userid; // 判断是哪一个用户的
              res.send({
                code: "200",
                message: "登录成功",
                data: {
                  token,
                  "refresh-token": refreshToken,
                  userid,
                },
              });
            }
          });
      }
    });
});

/**
 * @swagger
 * /api/user/wxlogin:
 *   post:
 *     summary: 微信小程序登录
 *     tags: [用户端-用户管理]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               code:
 *                 type: string
 *                 description: 微信授权码
 *             required:
 *               - code
 *     responses:
 *       200:
 *         description: 登录成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '登录成功'
 */
router.post("/wxlogin", (req, res, next) => {
  const { code } = req.body;
  axios
    .get(
      `https://api.weixin.qq.com/sns/jscode2session?appid=wx7e8b8b8b8b8b8b8b&secret=7e8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b&js_code=${code}&grant_type=authorization_code`
    )
    .then((r1) => {
      const { openid } = r1.data;
      mysql.find(User, { wx_openid: openid }).then((r2) => {
        const token = jwt.sign(
          { userid: r2[0].userid, wx_openid: openid },
          config.jwt.secret,
          {
            expiresIn: config.jwt.access_token_expires, // 7天
          }
        );
        
        // 生成refresh token，有效期更长
        const refreshToken = jwt.sign(
          { userid: r2[0].userid, wx_openid: openid, type: 'refresh' },
          config.jwt.refresh_secret,
          {
            expiresIn: config.jwt.refresh_token_expires, // 30天
          }
        );
        
        res.send({
          code: "200",
          message: "登录成功",
          token: token,
          "refresh-token": refreshToken,
          userid: r2[0].userid,
          wx_openid: openid,
        });
      });
    });
});

/**
 * @swagger
 * /api/user/info:
 *   get:
 *     summary: 获取用户信息
 *     tags: [用户端-用户管理]
 *     parameters:
 *       - in: query
 *         name: userid
 *         required: true
 *         schema:
 *           type: string
 *         description: 用户ID
 *       - in: header
 *         name: token
 *         required: true
 *         schema:
 *           type: string
 *         description: 访问令牌
 *     responses:
 *       200:
 *         description: 获取个人信息成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '获取个人信息'
 *                 data:
 *                   type: object
 *                   description: 用户信息
 *       401:
 *         description: token无效
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '10119'
 *                 message:
 *                   type: string
 *                   example: 'token无效'
 */
router.get("/info", (req, res, next) => {
  // token 可以通过 头信息，get /post 请求传递给后端
  const { token } = req.headers;
  // userid 通过get 传递
  const { userid } = req.query;
  // 验证token的有效性
  if (token) {
    // token 存在
    // console.log(1111111)
    // 验证token的有效性
    jwt.verify(token, config.jwt.secret, (err, decoded) => {
      if (err) {
        // console.log(33333)
        // token无效
        res.send({
          code: "10019",
          message: "token无效",
        });
      } else {
        req.decoded = decoded;
        // console.log(4444)
        //  token 有效 --- 返回个人信息
        mysql
          .find(User, { userid }, { _id: 0, __v: 0, password: 0 })
          .then((data) => {
            res.send({
              code: "200",
              message: "获取个人信息",
              data,
            });
          });
      }
    });
  } else {
    // token 不存在
    // console.log(22222)
    res.send({
      code: "10019",
      message: "token无效",
    });
  }
});
/**
 * @swagger
 * /api/user/orderlist:
 *   post:
 *     summary: 查看全部订单
 *     tags: [用户端-订单管理]
 *     parameters:
 *       - in: header
 *         name: token
 *         required: true
 *         schema:
 *           type: string
 *         description: 访问令牌
 *       - in: query
 *         name: userid
 *         required: true
 *         schema:
 *           type: string
 *         description: 用户ID
 *     responses:
 *       200:
 *         description: 查看全部订单成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '查看全部订单'
 *                 data:
 *                   type: array
 *                   description: 订单列表数据
 */
// 查看订单信息
router.post("/orderlist", (req, res, next) => {
  const { userid } = req.query;
  mysql.find(Order, { userid }, { _id: 0, __v: 0 }).then((data) => {
    res.send({
      code: "200",
      message: "查看全部订单",
      data,
    });
  });
});

/**
 * @swagger
 * /api/user/updatePassword:
 *   get:
 *     summary: 修改密码
 *     tags: [用户端-用户管理]
 *     parameters:
 *       - in: header
 *         name: token
 *         required: true
 *         schema:
 *           type: string
 *         description: 访问令牌
 *       - in: query
 *         name: userid
 *         required: true
 *         schema:
 *           type: string
 *         description: 用户ID
 *       - in: query
 *         name: oldpassword
 *         required: true
 *         schema:
 *           type: string
 *         description: 旧密码
 *       - in: query
 *         name: newpassword
 *         required: true
 *         schema:
 *           type: string
 *         description: 新密码
 *     responses:
 *       200:
 *         description: 密码修改成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '密码修改成功'
 *       400:
 *         description: 原始密码错误
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '10030'
 *                 message:
 *                   type: string
 *                   example: '原始密码错误'
 */
// 修改密码
router.get("/updatePassword", (req, res, next) => {
  const { userid, oldpassword, newpassword } = req.query;
  mysql
    .find(User, { userid, password: md5(oldpassword) }, { _id: 0, __v: 0 })
    .then((data) => {
      if (data.length === 0) {
        res.send({
          code: "10030",
          message: "原始密码错误",
        });
      } else {
        mysql
          .update(User, { userid }, { $set: { password: newpassword } })
          .then(() => {
            res.send({
              code: "200",
              message: "密码修改成功",
            });
          });
      }
    });
});

/**
 * @swagger
 * /api/user/bindusername:
 *   get:
 *     summary: 绑定用户名
 *     tags: [用户端-用户管理]
 *     parameters:
 *       - in: header
 *         name: token
 *         required: true
 *         schema:
 *           type: string
 *         description: 访问令牌
 *       - in: query
 *         name: userid
 *         required: true
 *         schema:
 *           type: string
 *         description: 用户ID
 *       - in: query
 *         name: username
 *         required: true
 *         schema:
 *           type: string
 *         description: 用户名
 *     responses:
 *       200:
 *         description: 绑定用户名成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '绑定用户名'
 */
// 绑定用户名
router.get("/bindusername", (req, res, next) => {
  const { userid, username } = req.query;
  mysql.update(User, { userid }, { $set: { username } }).then(() => {
    res.send({
      code: "200",
      message: "绑定用户名",
    });
  });
});

/**
 * @swagger
 * /api/user/binduseravatar:
 *   get:
 *     summary: 绑定头像
 *     tags: [用户端-用户管理]
 *     parameters:
 *       - in: header
 *         name: token
 *         required: true
 *         schema:
 *           type: string
 *         description: 访问令牌
 *       - in: query
 *         name: userid
 *         required: true
 *         schema:
 *           type: string
 *         description: 用户ID
 *       - in: query
 *         name: avatar
 *         required: true
 *         schema:
 *           type: string
 *         description: 头像地址
 *     responses:
 *       200:
 *         description: 绑定头像成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '头像'
 */
router.get("/binduseravatar", (req, res, next) => {
  const { userid, avatar } = req.query;
  mysql.update(User, { userid }, { $set: { avatar } }).then(() => {
    res.send({
      code: "200",
      message: "头像",
    });
  });
});

/**
 * @swagger
 * /api/user/refresh-token:
 *   post:
 *     summary: 刷新访问令牌
 *     tags: [用户端-用户管理]
 *     description: 使用refresh-token获取新的token和refresh-token
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               refresh-token:
 *                 type: string
 *                 description: 刷新令牌
 *             required:
 *               - refresh-token
 *     responses:
 *       200:
 *         description: 刷新成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '200'
 *                 message:
 *                   type: string
 *                   example: '刷新成功'
 *                 data:
 *                   type: object
 *                   properties:
 *                     token:
 *                       type: string
 *                       description: 新的访问令牌
 *                     refresh-token:
 *                       type: string
 *                       description: 新的刷新令牌
 *                     userid:
 *                       type: string
 *                       description: 用户ID
 *       400:
 *         description: refresh-token无效或已过期
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: string
 *                   example: '10020'
 *                 message:
 *                   type: string
 *                   example: 'refresh-token无效或已过期'
 */
router.post("/refresh-token", (req, res, next) => {
  const { "refresh-token": refreshToken } = req.body;
  
  if (!refreshToken) {
    return res.send({
      code: "10020",
      message: "refresh-token不能为空",
    });
  }
  
  // 验证refresh-token的有效性
  jwt.verify(refreshToken, config.jwt.refresh_secret, (err, decoded) => {
    if (err) {
      // refresh-token无效或已过期
      res.send({
        code: "10020",
        message: "refresh-token无效或已过期",
      });
    } else {
      // 检查是否是refresh类型的token
      if (decoded.type !== 'refresh') {
        return res.send({
          code: "10020",
          message: "无效的refresh-token类型",
        });
      }
      
      // refresh-token有效，生成新的token和refresh-token
      const newToken = jwt.sign(
        { tel: decoded.tel, userid: decoded.userid },
        config.jwt.secret,
        {
          expiresIn: config.jwt.access_token_expires, // 7天
        }
      );
      
      const newRefreshToken = jwt.sign(
        { tel: decoded.tel, userid: decoded.userid, type: 'refresh' },
        config.jwt.refresh_secret,
        {
          expiresIn: config.jwt.refresh_token_expires, // 30天
        }
      );
      
      res.send({
        code: "200",
        message: "刷新成功",
        data: {
          token: newToken,
          "refresh-token": newRefreshToken,
          userid: decoded.userid,
        },
      });
    }
  });
});

module.exports = router;
